package xiaojian.toolkit.jmx.model;

import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xiaojian.toolkit.jmx.util.MBeanServerConnectionSource;

public class AttributesSnapshotCache {
	private static final Logger LOG = LoggerFactory
			.getLogger(AttributesSnapshotCache.class);
	private final MBeanServerConnectionSource _source;

	public AttributesSnapshotCache(MBeanServerConnectionSource source) {
		this._source = source;
	}

	public AttributesSnapshot getSnapshotOf(String key, FeaturesDescription desc) {
		SnapshotUnion union = createOrGetUnion(key);

		AttributesSnapshot snapshot = (AttributesSnapshot) union.get(desc);
		if (null != snapshot) {
			return snapshot;
		}
		MBeanServerConnection mbsc = this._source.getMBeanServerConnection(key);
		if (null == mbsc) {
			LOG.warn(
					"can't get MBeanServerConnection for {}, return null for config {}",
					key, desc);

			return null;
		}
		snapshot = new FeaturesLoader(mbsc).loadAttributesSnapshot(desc);
		if (null == snapshot) {
			LOG.warn(
					"can't get AttributesSnapshot for {}/config {}, return null",
					key, desc);

			return null;
		}
		union.put(desc, snapshot);

		return snapshot;
	}

	public void invalidSnapshotOf(String key, FeaturesDescription desc) {
		SnapshotUnion union = getUnion(key);
		if (null != union) {
			union.remove(desc);
		}
	}

	public boolean isSnapshotExist(String key, FeaturesDescription desc) {
		SnapshotUnion union = getUnion(key);
		if (null != union) {
			return null != union.get(desc);
		}
		return false;
	}

	public SnapshotUnion getUnion(String key) {
		return (SnapshotUnion) this._snapshots.get(key);
	}

	public SnapshotUnion createOrGetUnion(String key) {
		SnapshotUnion union = (SnapshotUnion) this._snapshots.get(key);
		if (null == union) {
			union = new SnapshotUnion();
			this._snapshots.put(key, union);
		}
		return union;
	}

	private final Map<String, SnapshotUnion> _snapshots = new HashMap();

	private static class SnapshotUnion extends
			HashMap<FeaturesDescription, AttributesSnapshot> {
		private static final long serialVersionUID = 1L;
	}
}
